package com.duke.javaagent.bytebuddy02;



import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.NamedElement;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;

import java.lang.instrument.Instrumentation;

/**
 * @author gjy
 * @create 2024-11-22 11:28 AM
 */
public class AgentMain {
    private static final String CLASS_NAME = "com.duke.business.service.sb01.demos.utils.StringUtil";
    /**
     * 静态加载模式
     * premain 方法在目标 JVM 中实际运行 agent 的线程中执行，因此 premain 方法不能修改目标 JVM 的状态。
     *
     * 参数：agentArgs agent参数
     * instrumentation agent运行时的环境
     * @param agentArgs
     * @param inst
     */
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("bytebuddy  preMain 执行了...");

        new AgentBuilder.Default()
                //当目标类 第一次加载时，会执行下方.type 方法 去检查。
//                .type(ElementMatchers.named(CLASS_NAME))
                .type(getTypeMatcher())
                //当 被type 方法 匹配后，进入 transform 方法
                .transform(new AgentTransformer())
//                .with(new ByteListener())
                .installOn(inst);


        System.out.println("Agent setup complete!");

    }

    private static ElementMatcher<? super TypeDescription> getTypeMatcher() {
        //判断名称相等的第一种方式
//        return ElementMatchers.named(CLASS_NAME);

        //判断名称相等的第二种方式  动态的判断
        return new ElementMatcher.Junction.AbstractBase<NamedElement>(){
            @Override
            public boolean matches(NamedElement target) {
                return CLASS_NAME.equals(target.getActualName());
            }
        };
    }
    /**
     * 动态加载模式
     * agentmain 方法在目标 JVM 中实际运行 agent 的线程中执行，因此 agentmain 方法不能修改目标 JVM 的状态。
     * agentmain方法在 premain 方法之后执行，并且是在目标JVM 中实际运行 agent 的线程中执行，因此 agentmain 方法可以修改目标 JVM 的状态。
     *
     * 参数：agentArgs agent参数
     * instrumentation agent运行时的环境
     * @param agentArgs
     * @param inst
     */
    public static void agentmain(String agentArgs, Instrumentation inst) {
        System.out.println("agentmain 执行了...");
    }




}
